#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "modelpreview.h"
#include <QFileInfo>
#include <QDir>
#include <QApplication>
#include <QMenuBar>
#include <QStatusBar>
#include <QAction>
#include <QTabWidget>
#include <QScrollArea>
#include <QGroupBox>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QSpacerItem>
#include <QTimer>
#include <QMetaObject>
#include <QSplitter>
#include <QListWidget>
#include <QList>
#include <QDesktopServices>
#include <QUrl>
#include <QSizePolicy>
#include <cmath>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <QDebug> // Added for qDebug
#include <QThread>
#include <QByteArray>
#include <QFile>
#include <QIODevice>
#include <QElapsedTimer>

// 从内存加载的构造函数
ModelLoaderThread::ModelLoaderThread(const QByteArray& fileData, const QString& fileName, unsigned int flags, QObject* parent)
    : QThread(parent), m_fileData(fileData), m_fileName(fileName), m_flags(flags), m_useMemory(true) {}

// 从文件加载的构造函数（保持兼容性）
ModelLoaderThread::ModelLoaderThread(const QString& filePath, unsigned int flags, QObject* parent)
    : QThread(parent), m_filePath(filePath), m_flags(flags), m_useMemory(false) {}

void ModelLoaderThread::run() {
    Assimp::Importer* importer = new Assimp::Importer();
    const aiScene* scene = nullptr;
    
    // 添加性能计时器
    QElapsedTimer timer;
    timer.start();
    
    if (m_useMemory) {
        // 从内存加载模型
        qDebug() << "🔄 开始从内存加载模型:" << m_fileName;
        
        scene = importer->ReadFileFromMemory(
                    m_fileData.constData(),
                    m_fileData.size(),
                    m_flags,
                    m_fileName.toLocal8Bit().constData()
                    );
        
        qint64 loadTime = timer.nsecsElapsed();
        qDebug() << "✅ 内存加载完成，耗时:" << loadTime / 1000000.0 << "毫秒";
        
    } else {
        qDebug() << "🔄 开始从文件加载模型:" << m_filePath;
        
        QFileInfo fileInfo(m_filePath);    
        scene = importer->ReadFile(m_filePath.toStdString(), m_flags);
        
        qint64 loadTime = timer.nsecsElapsed();
        qDebug() << "✅ 文件加载完成，耗时:" << loadTime / 1000000.0 << "毫秒";
    }

    if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
        QString errorStr(importer->GetErrorString());
        emit loadError(errorStr);
        delete importer;
    } else {
        QString finalPath = m_useMemory ? m_fileName : m_filePath;
        emit modelLoaded(scene, importer, finalPath);
    }
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_optimizer(new ModelOptimizer(this))
    , m_modelPreview(new ModelPreview(this))
    , m_logDialog(new LogDialog(this))
{
    ui->setupUi(this);
    setupUI();
    setupMenuBar();
    
    // 连接信号和槽
    connect(m_optimizer, &ModelOptimizer::progressUpdated, this, &MainWindow::onProgressUpdated);
    connect(m_optimizer, &ModelOptimizer::optimizationCompleted, this, &MainWindow::onOptimizationCompleted);
    connect(m_optimizer, &ModelOptimizer::errorOccurred, this, &MainWindow::onErrorOccurred);
    
    setWindowTitle("3D模型轻量化工具 - Assimp");
    resize(1200, 800);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setupUI()
{
    // 获取UI中的控件
    m_inputFileEdit = ui->inputFileEdit;
    m_outputFileEdit = ui->outputFileEdit;
    
    // 将ModelPreview添加到modelPreviewContainer中
    QWidget *modelPreviewContainer = ui->modelPreviewContainer;
    QVBoxLayout *modelPreviewLayout = new QVBoxLayout(modelPreviewContainer);
    modelPreviewLayout->setContentsMargins(0, 0, 0, 0);
    modelPreviewLayout->addWidget(m_modelPreview);
    
    // 设置ModelPreview的大小策略
    m_modelPreview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    m_modelPreview->setMinimumSize(400, 350); // 增加最小高度，从300增加到350
    
    // 动画控制UI现在在UI文件中定义
    createAnimationControls();
    
    // 修复QSplitter大小设置问题
    // 查找所有QSplitter并正确设置其大小
    QList<QSplitter*> splitters = this->findChildren<QSplitter*>();
    for (QSplitter* splitter : splitters) {
        // 正确设置 splitter 大小，使用 QList<int> 而不是 QSize
        QList<int> sizes;
        QWidget* parent = splitter->parentWidget();
        if (parent) {
            sizes << parent->width() / 2 << parent->width() / 2;
        } else {
            sizes << 400 << 400;
        }
        splitter->setSizes(sizes);
    }
    
    // 如果你有特定名称的 splitter，也可以直接这样设置:
    // someSplitter->setSizes(QList<int>() << 400 << 400);
    
    m_inputFileButton = ui->inputFileButton;
    m_outputFileButton = ui->outputFileButton;
    
    // 新增预览按钮
    QPushButton *previewButton = ui->previewButton;
    

    
    // 初始化新增的预览按钮
    m_inputPreviewButton = ui->inputPreviewButton;
    m_outputPreviewButton = ui->outputPreviewButton;
    
    // 确保预览按钮可见并启用
    previewButton->setVisible(true);
    previewButton->setEnabled(true);

    
    m_startButton = ui->startButton;
    m_stopButton = ui->stopButton;
    m_progressBar = ui->progressBar;
    m_progressPercentLabel = ui->progressPercentLabel;
    
    // 基础优化选项
    m_vertexReductionSpinBox = ui->vertexReductionSpinBox;
    m_normalToleranceSpinBox = ui->normalToleranceSpinBox;
    m_uvToleranceSpinBox = ui->uvToleranceSpinBox;
    
    // 网格优化选项
    m_removeUnusedVerticesCheckBox = ui->removeUnusedVerticesCheckBox;
    m_joinIdenticalVerticesCheckBox = ui->joinIdenticalVerticesCheckBox;

    m_triangulateCheckBox = ui->triangulateCheckBox;
    m_improveCacheLocalityCheckBox = ui->improveCacheLocalityCheckBox;
    m_optimizeMeshesCheckBox = ui->optimizeMeshesCheckBox;
    
    // 法线处理选项
    m_generateNormalsCheckBox = ui->generateNormalsCheckBox;
    m_generateSmoothNormalsCheckBox = ui->generateSmoothNormalsCheckBox;
    m_calculateTangentSpaceCheckBox = ui->calculateTangentSpaceCheckBox;
    m_fixInfacingNormalsCheckBox = ui->fixInfacingNormalsCheckBox;
    
    // 材质优化选项
    m_removeRedundantMaterialsCheckBox = ui->removeRedundantMaterialsCheckBox;
    m_embedTexturesCheckBox = ui->embedTexturesCheckBox;
    
    // 数据验证选项
    m_findDegeneratesCheckBox = ui->findDegeneratesCheckBox;
    m_findInvalidDataCheckBox = ui->findInvalidDataCheckBox;
    m_validateDataStructureCheckBox = ui->validateDataStructureCheckBox;
    m_optimizeGraphCheckBox = ui->optimizeGraphCheckBox;
    
    // 高级选项
    m_sortByPTypeCheckBox = ui->sortByPTypeCheckBox;
    m_preTransformVerticesCheckBox = ui->preTransformVerticesCheckBox;
    m_splitLargeMeshesCheckBox = ui->splitLargeMeshesCheckBox;
    m_limitBoneWeightsCheckBox = ui->limitBoneWeightsCheckBox;
    m_flipUVsCheckBox = ui->flipUVsCheckBox;
    m_flipWindingOrderCheckBox = ui->flipWindingOrderCheckBox;
    m_splitByBoneCountCheckBox = ui->splitByBoneCountCheckBox;
    m_deboneCheckBox = ui->deboneCheckBox;
    m_forceGenNormalsCheckBox = ui->forceGenNormalsCheckBox;
    m_dropNormalsCheckBox = ui->dropNormalsCheckBox;
    m_genUVCoordsCheckBox = ui->genUVCoordsCheckBox;
    m_transformUVCoordsCheckBox = ui->transformUVCoordsCheckBox;
    m_findInstancesCheckBox = ui->findInstancesCheckBox;
    m_reverseWindingOrderCheckBox = ui->reverseWindingOrderCheckBox;
    m_invertNormalsCheckBox = ui->invertNormalsCheckBox;
    
    // 模型预览缩放控制
    m_scaleLabel = ui->scaleLabel;
    m_scaleSlider = ui->scaleSlider;
    m_scaleSpinBox = ui->scaleSpinBox;
    m_resetScaleButton = ui->resetScaleButton;
    m_resetViewButton = ui->resetViewButton;
    
    // 连接信号和槽
    connect(m_inputFileButton, &QPushButton::clicked, this, &MainWindow::onSelectInputFile);
    connect(m_outputFileButton, &QPushButton::clicked, this, &MainWindow::onSelectOutputFile);
    connect(previewButton, &QPushButton::clicked, this, &MainWindow::onPreviewModel);

    connect(m_startButton, &QPushButton::clicked, this, &MainWindow::onStartOptimization);
    connect(m_stopButton, &QPushButton::clicked, this, &MainWindow::onStopOptimization);
    
    // 连接新增预览按钮的信号和槽
    connect(m_inputPreviewButton, &QPushButton::clicked, this, &MainWindow::onInputPreviewClicked);
    connect(m_outputPreviewButton, &QPushButton::clicked, this, &MainWindow::onOutputPreviewClicked);
    
    // 连接缩放控制的信号和槽
    connect(m_scaleSlider, &QSlider::valueChanged, this, &MainWindow::onScaleSliderChanged);
    connect(m_scaleSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &MainWindow::onScaleSpinBoxChanged);
    connect(m_resetScaleButton, &QPushButton::clicked, this, &MainWindow::onResetScaleClicked);
    connect(m_resetViewButton, &QPushButton::clicked, this, &MainWindow::onResetViewClicked);
    
    // 连接模型预览的信号
    connect(m_modelPreview, &ModelPreview::scaleChanged, this, &MainWindow::onModelPreviewScaleChanged);
    connect(m_modelPreview, &ModelPreview::animationListChanged, this, &MainWindow::onAnimationListChanged);
    connect(m_modelPreview, &ModelPreview::animationStateChanged, this, &MainWindow::onAnimationStateChanged);
    
    // 连接视图控制按钮
    connect(ui->frontViewButton, &QPushButton::clicked, this, &MainWindow::onFrontViewClicked);
    connect(ui->backViewButton, &QPushButton::clicked, this, &MainWindow::onBackViewClicked);
    connect(ui->leftViewButton, &QPushButton::clicked, this, &MainWindow::onLeftViewClicked);
    connect(ui->rightViewButton, &QPushButton::clicked, this, &MainWindow::onRightViewClicked);
    connect(ui->topViewButton, &QPushButton::clicked, this, &MainWindow::onTopViewClicked);
    connect(ui->bottomViewButton, &QPushButton::clicked, this, &MainWindow::onBottomViewClicked);
    
    // 连接相机控制
    connect(ui->rotationSensitivitySlider, &QSlider::valueChanged, this, &MainWindow::onRotationSensitivityChanged);
    connect(ui->autoAdjustCameraCheckBox, &QCheckBox::toggled, this, &MainWindow::onAutoAdjustCameraChanged);
    
    // 设置状态栏
    statusBar()->showMessage("就绪");
    
    // UI文件中已经设置了分割器的初始大小，这里不需要再设置
}

void MainWindow::createAnimationControls()
{
    // 动画控制UI现在在UI文件中定义，只需要连接信号和槽
    connect(ui->playAnimationButton, &QPushButton::clicked, this, &MainWindow::onPlayAnimationClicked);
    connect(ui->stopAnimationButton, &QPushButton::clicked, this, &MainWindow::onStopAnimationClicked);
    connect(ui->pauseAnimationButton, &QPushButton::clicked, this, &MainWindow::onPauseAnimationClicked);
    connect(ui->resumeAnimationButton, &QPushButton::clicked, this, &MainWindow::onResumeAnimationClicked);
    connect(ui->animationListWidget, &QListWidget::itemDoubleClicked, this, &MainWindow::onAnimationListItemDoubleClicked);
    
    // 初始状态：禁用按钮
    ui->playAnimationButton->setEnabled(false);
    ui->stopAnimationButton->setEnabled(false);
    ui->pauseAnimationButton->setEnabled(false);
    ui->resumeAnimationButton->setEnabled(false);
}

void MainWindow::setupMenuBar()
{
    // 连接UI文件中已定义的菜单动作
    m_actionOpen = ui->actionOpen;
    m_actionPreview = ui->actionPreview;
    m_actionExit = ui->actionExit;
    m_actionAbout = ui->actionAbout;
    
    // 连接信号和槽
    connect(m_actionOpen, &QAction::triggered, this, &MainWindow::onOpenModel);
    connect(m_actionPreview, &QAction::triggered, this, &MainWindow::onPreviewModel);
    connect(m_actionExit, &QAction::triggered, this, &MainWindow::onExit);
    connect(m_actionAbout, &QAction::triggered, this, &MainWindow::onAbout);
    
    // 创建查看菜单（UI文件中没有定义）
    QMenu *viewMenu = menuBar()->addMenu("查看(&V)");
    m_actionShowLog = new QAction("日志(&L)", this);
    m_actionShowLog->setShortcut(QKeySequence("Ctrl+L"));
    connect(m_actionShowLog, &QAction::triggered, this, &MainWindow::onShowLogDialog);
    viewMenu->addAction(m_actionShowLog);
}

void MainWindow::onSelectInputFile()
{
    // 显示一个对话框让用户选择导入方式
    QMessageBox msgBox;
    msgBox.setText("选择导入方式");
    msgBox.setInformativeText("您想如何导入模型？");
    QPushButton *singleModelButton = msgBox.addButton("单个模型文件", QMessageBox::ActionRole);
    QPushButton *folderButton = msgBox.addButton("包含模型和贴图的文件夹", QMessageBox::ActionRole);
    QPushButton *multiFileButton = msgBox.addButton("多个文件（模型+贴图）", QMessageBox::ActionRole);
    QPushButton *cancelButton = msgBox.addButton(QMessageBox::Cancel);
    
    msgBox.exec();
    
    if (msgBox.clickedButton() == cancelButton) {
        return;
    }
    
    if (msgBox.clickedButton() == singleModelButton) {
        // 选择单个模型文件
        QFileDialog dialog(this);
        dialog.setFileMode(QFileDialog::ExistingFile);
        dialog.setNameFilter("3D Models (*.obj *.fbx *.dae *.gltf *.glb *.3ds *.stl);;All Files (*)");
        dialog.setViewMode(QFileDialog::Detail);
        
        if (dialog.exec()) {
            QStringList fileNames = dialog.selectedFiles();
            if (!fileNames.isEmpty()) {
                QString inputPath = fileNames.first();
                m_inputFileEdit->setText(inputPath);
                
                // 自动填充输出文件路径
                if (m_outputFileEdit->text().isEmpty()) {
                    QFileInfo inputFileInfo(inputPath);
                    QString outputDir = inputFileInfo.absolutePath() + "/optimized";
                    QDir().mkpath(outputDir);  // 确保目录存在
                    
                    // 构造输出文件路径
                    QString outputFileName = inputFileInfo.baseName() + "_optimized." + inputFileInfo.suffix();
                    QString outputFilePath = outputDir + "/" + outputFileName;
                    
                    m_outputFileEdit->setText(outputFilePath);
                }
            }
        }
    }
    else if (msgBox.clickedButton() == folderButton) {
        // 选择包含模型和贴图的文件夹
        QString folderPath = QFileDialog::getExistingDirectory(this, "选择包含模型和贴图的文件夹");
        if (!folderPath.isEmpty()) {
            QDir folderDir(folderPath);
            QStringList modelFilters;
            modelFilters << "*.obj" << "*.fbx" << "*.dae" << "*.gltf" << "*.glb" << "*.3ds" << "*.stl";
            
            QStringList modelFiles = folderDir.entryList(modelFilters, QDir::Files | QDir::Readable);
            if (modelFiles.isEmpty()) {
                QMessageBox::warning(this, "警告", "所选文件夹中没有找到支持的模型文件！");
                return;
            }
            
            // 如果只有一个模型文件，直接使用它
            if (modelFiles.size() == 1) {
                QString modelPath = folderDir.filePath(modelFiles.first());
                m_inputFileEdit->setText(modelPath);
                
                // 自动填充输出文件路径
                if (m_outputFileEdit->text().isEmpty()) {
                    QFileInfo inputFileInfo(modelPath);
                    QString outputDir = inputFileInfo.absolutePath() + "/optimized";
                    QDir().mkpath(outputDir);
                    
                    QString outputFileName = inputFileInfo.baseName() + "_optimized." + inputFileInfo.suffix();
                    QString outputFilePath = outputDir + "/" + outputFileName;
                    
                    m_outputFileEdit->setText(outputFilePath);
                }
            }
            else {
                // 如果有多个模型文件，让用户选择一个
                bool ok;
                QString selectedModel = QInputDialog::getItem(this, "选择模型文件",
                                                              "文件夹中有多个模型文件，请选择一个:",
                                                              modelFiles, 0, false, &ok);
                if (ok && !selectedModel.isEmpty()) {
                    QString modelPath = folderDir.filePath(selectedModel);
                    m_inputFileEdit->setText(modelPath);
                    
                    // 自动填充输出文件路径
                    if (m_outputFileEdit->text().isEmpty()) {
                        QFileInfo inputFileInfo(modelPath);
                        QString outputDir = inputFileInfo.absolutePath() + "/optimized";
                        QDir().mkpath(outputDir);
                        
                        QString outputFileName = inputFileInfo.baseName() + "_optimized." + inputFileInfo.suffix();
                        QString outputFilePath = outputDir + "/" + outputFileName;
                        
                        m_outputFileEdit->setText(outputFilePath);
                    }
                }
            }
        }
    }
    else if (msgBox.clickedButton() == multiFileButton) {
        // 选择多个文件（模型+贴图）
        QFileDialog dialog(this);
        dialog.setFileMode(QFileDialog::ExistingFiles);
        dialog.setNameFilter("All Supported Files (*.obj *.fbx *.dae *.gltf *.glb *.3ds *.stl *.png *.jpg *.jpeg *.bmp *.tga *.tif *.tiff);;3D Models (*.obj *.fbx *.dae *.gltf *.glb *.3ds *.stl);;Textures (*.png *.jpg *.jpeg *.bmp *.tga *.tif *.tiff);;All Files (*)");
        dialog.setViewMode(QFileDialog::Detail);
        
        if (dialog.exec()) {
            QStringList fileNames = dialog.selectedFiles();
            if (!fileNames.isEmpty()) {
                // 筛选出模型文件
                QStringList modelFiles;
                for (const QString &file : fileNames) {
                    QFileInfo fileInfo(file);
                    QString suffix = fileInfo.suffix().toLower();
                    if (suffix == "obj" || suffix == "fbx" || suffix == "dae" ||
                            suffix == "gltf" || suffix == "glb" || suffix == "3ds" || suffix == "stl") {
                        modelFiles.append(file);
                    }
                }
                
                if (modelFiles.isEmpty()) {
                    QMessageBox::warning(this, "警告", "没有选择有效的模型文件！");
                    return;
                }
                
                // 如果只有一个模型文件，直接使用它
                if (modelFiles.size() == 1) {
                    QString modelPath = modelFiles.first();
                    m_inputFileEdit->setText(modelPath);
                    
                    // 自动填充输出文件路径
                    if (m_outputFileEdit->text().isEmpty()) {
                        QFileInfo inputFileInfo(modelPath);
                        QString outputDir = inputFileInfo.absolutePath() + "/optimized";
                        QDir().mkpath(outputDir);
                        
                        QString outputFileName = inputFileInfo.baseName() + "_optimized." + inputFileInfo.suffix();
                        QString outputFilePath = outputDir + "/" + outputFileName;
                        
                        m_outputFileEdit->setText(outputFilePath);
                    }
                }
                else {
                    // 如果有多个模型文件，让用户选择一个
                    bool ok;
                    QString selectedModel = QInputDialog::getItem(this, "选择模型文件",
                                                                  "选择了多个模型文件，请选择一个:",
                                                                  modelFiles, 0, false, &ok);
                    if (ok && !selectedModel.isEmpty()) {
                        m_inputFileEdit->setText(selectedModel);
                        
                        // 自动填充输出文件路径
                        if (m_outputFileEdit->text().isEmpty()) {
                            QFileInfo inputFileInfo(selectedModel);
                            QString outputDir = inputFileInfo.absolutePath() + "/optimized";
                            QDir().mkpath(outputDir);
                            
                            QString outputFileName = inputFileInfo.baseName() + "_optimized." + inputFileInfo.suffix();
                            QString outputFilePath = outputDir + "/" + outputFileName;
                            
                            m_outputFileEdit->setText(outputFilePath);
                        }
                    }
                }
            }
        }
    }
}

void MainWindow::onSelectOutputFile()
{
    QString dirPath = QFileDialog::getExistingDirectory(this, "选择输出目录", QDir::homePath(),
                                                        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (!dirPath.isEmpty()) {
        m_outputFileEdit->setText(dirPath);
    }
}

// 新增函数：选择模型或文件夹
void MainWindow::onSelectModelOrFolder()
{
    QMessageBox msgBox;
    msgBox.setText("选择导入方式");
    QPushButton *singleFileButton = msgBox.addButton("单个模型文件", QMessageBox::ActionRole);
    QPushButton *folderButton = msgBox.addButton("模型文件夹", QMessageBox::ActionRole);
    msgBox.addButton(QMessageBox::Cancel);
    
    msgBox.exec();
    
    if (msgBox.clickedButton() == singleFileButton) {
        // 选择单个模型文件
        onSelectSingleModel();
    } else if (msgBox.clickedButton() == folderButton) {
        // 选择模型文件夹
        onSelectModelFolder();
    }
}

void MainWindow::onSelectSingleModel()
{
    QFileDialog dialog(this);
    dialog.setFileMode(QFileDialog::ExistingFile);
    dialog.setNameFilter("3D Models (*.obj *.fbx *.dae *.gltf *.glb *.3ds *.stl);;All Files (*)");
    dialog.setViewMode(QFileDialog::Detail);
    
    if (dialog.exec()) {
        QStringList fileNames = dialog.selectedFiles();
        if (!fileNames.isEmpty()) {
            QString inputPath = fileNames.first();
            m_inputFileEdit->setText(inputPath);
            
            // 自动填充输出文件路径
            if (m_outputFileEdit->text().isEmpty()) {
                QFileInfo inputFileInfo(inputPath);
                QString outputDir = inputFileInfo.absolutePath() + "/optimized";
                QDir().mkpath(outputDir);  // 确保目录存在
                
                // 构造输出文件路径
                QString outputFileName = inputFileInfo.baseName() + "_optimized." + inputFileInfo.suffix();
                QString outputFilePath = outputDir + "/" + outputFileName;
                
                m_outputFileEdit->setText(outputFilePath);
            }
        }
    }
}

void MainWindow::onSelectModelFolder()
{
    QString dirPath = QFileDialog::getExistingDirectory(this, "选择模型文件夹", QDir::homePath(),
                                                        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (!dirPath.isEmpty()) {
        loadModelsFromFolder(dirPath);
    }
}

void MainWindow::loadModelsFromFolder(const QString &folderPath)
{
    QDir dir(folderPath);
    QStringList filters;
    filters << "*.obj" << "*.fbx" << "*.dae" << "*.gltf" << "*.glb" << "*.3ds" << "*.stl";
    
    QStringList modelFiles = dir.entryList(filters, QDir::Files | QDir::Readable, QDir::Name);
    if (modelFiles.isEmpty()) {
        QMessageBox::warning(this, "警告", "文件夹中没有找到支持的模型文件！");
        return;
    }
    
    // 显示模型选择对话框
    QDialog dialog(this);
    QVBoxLayout layout(&dialog);
    QListWidget listWidget;
    
    for (const QString &fileName : modelFiles) {
        listWidget.addItem(fileName);
    }
    
    QPushButton selectButton("选择");
    connect(&selectButton, &QPushButton::clicked, &dialog, &QDialog::accept);
    
    layout.addWidget(&listWidget);
    layout.addWidget(&selectButton);
    
    if (dialog.exec() == QDialog::Accepted && listWidget.currentItem()) {
        QString selectedModel = listWidget.currentItem()->text();
        QString modelPath = dir.filePath(selectedModel);
        m_inputFileEdit->setText(modelPath);
        
        // 自动填充输出文件路径
        if (m_outputFileEdit->text().isEmpty()) {
            QFileInfo inputFileInfo(modelPath);
            QString outputDir = inputFileInfo.absolutePath() + "/optimized";
            QDir().mkpath(outputDir);
            
            QString outputFileName = inputFileInfo.baseName() + "_optimized." + inputFileInfo.suffix();
            QString outputFilePath = outputDir + "/" + outputFileName;
            
            m_outputFileEdit->setText(outputFilePath);
        }
    }
}

void MainWindow::onStartOptimization()
{
    QString inputPath = m_inputFileEdit->text().trimmed();
    QString outputPath = m_outputFileEdit->text().trimmed();
    
    if (inputPath.isEmpty()) {
        QMessageBox::warning(this, "警告", "请选择输入文件！");
        return;
    }
    
    if (outputPath.isEmpty()) {
        QMessageBox::warning(this, "警告", "请选择输出文件！");
        return;
    }
    
    if (!QFile::exists(inputPath)) {
        QMessageBox::warning(this, "错误", "输入文件不存在！");
        return;
    }
    
    // 构建优化选项
    ModelOptimizer::OptimizationOptions options;
    
    // 基础参数
    options.vertexReduction = m_vertexReductionSpinBox->value() / 100.0f; // 转换为0-1范围
    options.normalTolerance = m_normalToleranceSpinBox->value();
    options.uvTolerance = m_uvToleranceSpinBox->value();
    options.globalScale = 1.0f; // 默认值，UI中没有对应控件
    
    // 网格优化选项
    options.removeUnusedVertices = m_removeUnusedVerticesCheckBox->isChecked();
    options.joinIdenticalVertices = m_joinIdenticalVerticesCheckBox->isChecked();
    options.optimizeMeshes = m_optimizeMeshesCheckBox->isChecked();
    options.triangulate = m_triangulateCheckBox->isChecked();
    options.improveCacheLocality = m_improveCacheLocalityCheckBox->isChecked();
    
    // 法线处理选项
    options.generateNormals = m_generateNormalsCheckBox->isChecked();
    options.generateSmoothNormals = m_generateSmoothNormalsCheckBox->isChecked();
    options.forceGenNormals = m_forceGenNormalsCheckBox->isChecked();
    options.dropNormals = m_dropNormalsCheckBox->isChecked();
    options.calculateTangentSpace = m_calculateTangentSpaceCheckBox->isChecked();
    options.fixInfacingNormals = m_fixInfacingNormalsCheckBox->isChecked();
    options.invertNormals = m_invertNormalsCheckBox->isChecked();
    
    // UV坐标处理选项
    options.genUVCoords = m_genUVCoordsCheckBox->isChecked();
    options.transformUVCoords = m_transformUVCoordsCheckBox->isChecked();
    options.flipUVs = m_flipUVsCheckBox->isChecked();
    
    // 材质优化选项
    options.removeRedundantMaterials = m_removeRedundantMaterialsCheckBox->isChecked();
    options.embedTextures = m_embedTexturesCheckBox->isChecked();
    
    // 骨骼处理选项
    options.limitBoneWeights = m_limitBoneWeightsCheckBox->isChecked();
    options.splitByBoneCount = m_splitByBoneCountCheckBox->isChecked();
    options.debone = m_deboneCheckBox->isChecked();
    
    // 缠绕顺序选项
    options.flipWindingOrder = m_flipWindingOrderCheckBox->isChecked();
    options.reverseWindingOrder = m_reverseWindingOrderCheckBox->isChecked();
    
    // 数据验证选项
    options.findDegenerates = m_findDegeneratesCheckBox->isChecked();
    options.findInvalidData = m_findInvalidDataCheckBox->isChecked();
    options.validateDataStructure = m_validateDataStructureCheckBox->isChecked();
    options.optimizeGraph = m_optimizeGraphCheckBox->isChecked();
    options.findInstances = m_findInstancesCheckBox->isChecked();
    
    // 高级选项
    options.sortByPType = m_sortByPTypeCheckBox->isChecked();
    options.preTransformVertices = m_preTransformVerticesCheckBox->isChecked();
    options.splitLargeMeshes = m_splitLargeMeshesCheckBox->isChecked();
    
    // 禁用控件
    enableControls(false);
    
    // 重置进度条
    m_progressBar->setValue(0);
    m_progressPercentLabel->setText("0%");
    
    // 清空日志
    m_logDialog->clearLog();
    m_logDialog->appendLogWithTimestamp("开始优化模型...");
    m_logDialog->appendLog("输入文件: " + inputPath);
    m_logDialog->appendLog("输出文件: " + outputPath);
    
    // 显示用户选择的优化选项
    m_logDialog->appendLog("\n📋 用户选择的优化选项:");
    
    // 基础参数
    if (options.vertexReduction > 0.0f) {
        m_logDialog->appendLog(QString("  • 顶点减少比例: %1%").arg(options.vertexReduction * 100, 0, 'f', 1));
    }
    if (options.normalTolerance > 0.0f) {
        m_logDialog->appendLog(QString("  • 法线容差: %1").arg(options.normalTolerance, 0, 'f', 3));
    }
    if (options.uvTolerance > 0.0f) {
        m_logDialog->appendLog(QString("  • UV容差: %1").arg(options.uvTolerance, 0, 'f', 3));
    }
    
    // 网格优化选项
    if (options.removeUnusedVertices) m_logDialog->appendLog("  • 移除未使用顶点");
    if (options.joinIdenticalVertices) m_logDialog->appendLog("  • 合并相同顶点");
    if (options.optimizeMeshes) m_logDialog->appendLog("  • 优化网格");
    if (options.triangulate) m_logDialog->appendLog("  • 三角化");
    if (options.improveCacheLocality) m_logDialog->appendLog("  • 改善缓存局部性");
    
    // 法线处理选项
    if (options.generateNormals) m_logDialog->appendLog("  • 生成法线");
    if (options.generateSmoothNormals) m_logDialog->appendLog("  • 生成平滑法线");
    if (options.forceGenNormals) m_logDialog->appendLog("  • 强制生成法线");
    if (options.dropNormals) m_logDialog->appendLog("  • 丢弃法线");
    if (options.calculateTangentSpace) m_logDialog->appendLog("  • 计算切线空间");
    if (options.fixInfacingNormals) m_logDialog->appendLog("  • 修复内面法线");
    if (options.invertNormals) m_logDialog->appendLog("  • 反转法线");
    
    // UV坐标处理选项
    if (options.genUVCoords) m_logDialog->appendLog("  • 生成UV坐标");
    if (options.transformUVCoords) m_logDialog->appendLog("  • 变换UV坐标");
    if (options.flipUVs) m_logDialog->appendLog("  • 翻转UV坐标");
    
    // 材质优化选项
    if (options.removeRedundantMaterials) m_logDialog->appendLog("  • 移除冗余材质");
    if (options.embedTextures) m_logDialog->appendLog("  • 嵌入纹理");
    
    // 骨骼处理选项
    if (options.limitBoneWeights) m_logDialog->appendLog("  • 限制骨骼权重");
    if (options.splitByBoneCount) m_logDialog->appendLog("  • 按骨骼数量分割");
    if (options.debone) m_logDialog->appendLog("  • 移除骨骼");
    
    // 缠绕顺序选项
    if (options.flipWindingOrder) m_logDialog->appendLog("  • 翻转缠绕顺序");
    if (options.reverseWindingOrder) m_logDialog->appendLog("  • 反转缠绕顺序");
    
    // 数据验证选项
    if (options.findDegenerates) m_logDialog->appendLog("  • 查找退化面");
    if (options.findInvalidData) m_logDialog->appendLog("  • 查找无效数据");
    if (options.validateDataStructure) m_logDialog->appendLog("  • 验证数据结构");
    if (options.optimizeGraph) m_logDialog->appendLog("  • 优化场景图");
    if (options.findInstances) m_logDialog->appendLog("  • 查找实例");
    
    // 高级选项
    if (options.sortByPType) m_logDialog->appendLog("  • 按类型排序");
    if (options.preTransformVertices) m_logDialog->appendLog("  • 预变换顶点");
    if (options.splitLargeMeshes) m_logDialog->appendLog("  • 分割大网格");
    
    m_logDialog->appendLog("\n🔧 开始执行优化...");
    
    // 显示日志对话框，显示优化过程
    if (m_logDialog && !m_logDialog->isVisible()) {
        m_logDialog->show();
    }
    
    statusBar()->showMessage("正在优化模型...");
    
    // 开始优化（使用新的线程化方法）
    m_optimizer->startOptimization(inputPath, outputPath, options);
}

void MainWindow::onStopOptimization()
{
    if (m_optimizer) {
        m_optimizer->cancelOptimization();
        m_logDialog->appendLogWithTimestamp("用户停止了优化过程");
        statusBar()->showMessage("正在取消优化...");
        
        // 确保显示日志对话框
        if (m_logDialog && !m_logDialog->isVisible()) {
            m_logDialog->show();
        }
    }
}

void MainWindow::onProgressUpdated(int percentage)
{
    m_progressBar->setValue(percentage);
    m_progressPercentLabel->setText(QString("%1%").arg(percentage));
    
    // 减少日志输出频率，避免界面卡顿
    static int lastLoggedPercentage = -1;
    if (percentage != lastLoggedPercentage && (percentage % 20 == 0 || percentage == 100 || percentage == 50)) {
        m_logDialog->appendLog(QString("优化进度: %1%").arg(percentage));
        lastLoggedPercentage = percentage;
    }
    
    // 确保在优化过程中始终显示日志对话框
    if (m_logDialog && !m_logDialog->isVisible()) {
        m_logDialog->show();
    }
}

void MainWindow::onOptimizationCompleted(const ModelOptimizer::OptimizationResult &result)
{
    if (result.success) {
        m_logDialog->appendLogWithTimestamp("✅ 优化完成！");
        m_logDialog->appendLog("📊 优化结果:");
        m_logDialog->appendLog(QString("   • 压缩比: %1%").arg(result.compressionRatio * 100, 0, 'f', 1));
        m_logDialog->appendLog(QString("   • 顶点数: %1 -> %2").arg(result.originalVertexCount).arg(result.optimizedVertexCount));
        m_logDialog->appendLog(QString("   • 面数: %1 -> %2").arg(result.originalFaceCount).arg(result.optimizedFaceCount));
        m_logDialog->appendLog(QString("   • 材质数: %1 -> %2").arg(result.originalMaterialCount).arg(result.optimizedMaterialCount));
        
        // 确保日志对话框可见，让用户查看完整的优化过程
        if (m_logDialog && !m_logDialog->isVisible()) {
            m_logDialog->show();
        }
        
        QMessageBox::information(this, "成功",
                                 QString("模型优化完成！\n"
                                         "压缩比: %1%\n"
                                         "顶点数: %2 -> %3\n"
                                         "面数: %4 -> %5\n\n"
                                         "注意：优化过程中可能出现了一些警告，请查看日志了解详情。")
                                 .arg(result.compressionRatio * 100, 0, 'f', 1)
                                 .arg(result.originalVertexCount)
                                 .arg(result.optimizedVertexCount)
                                 .arg(result.originalFaceCount)
                                 .arg(result.optimizedFaceCount));
        
        statusBar()->showMessage("优化完成");
    } else {
        m_logDialog->appendLogWithTimestamp("❌ 优化失败: " + result.errorMessage);
        QMessageBox::critical(this, "错误", "优化失败: " + result.errorMessage);
        statusBar()->showMessage("优化失败");
        
        // 确保显示日志对话框
        if (m_logDialog && !m_logDialog->isVisible()) {
            m_logDialog->show();
        }
    }
    
    // 重新启用控件
    enableControls(true);
    
    // 确保显示日志对话框
    if (m_logDialog && !m_logDialog->isVisible()) {
        m_logDialog->show();
    }
}

void MainWindow::onErrorOccurred(const QString &error)
{
    // 在日志中显示错误信息，但不弹出对话框（避免过多弹窗）
    m_logDialog->appendLogWithTimestamp("⚠️ 警告: " + error);
    
    // 更新状态栏
    statusBar()->showMessage("优化过程中出现警告，请查看日志");
    
    // 确保显示日志对话框
    if (m_logDialog && !m_logDialog->isVisible()) {
        m_logDialog->show();
    }
    
}

void MainWindow::enableControls(bool enable)
{
    m_inputFileEdit->setEnabled(enable);
    m_outputFileEdit->setEnabled(enable);
    m_inputFileButton->setEnabled(enable);
    m_outputFileButton->setEnabled(enable);
    m_startButton->setEnabled(enable);
    m_stopButton->setEnabled(!enable);
    
    // 优化选项控件
    m_vertexReductionSpinBox->setEnabled(enable);
    m_normalToleranceSpinBox->setEnabled(enable);
    m_uvToleranceSpinBox->setEnabled(enable);
    m_removeUnusedVerticesCheckBox->setEnabled(enable);
    m_joinIdenticalVerticesCheckBox->setEnabled(enable);

    m_triangulateCheckBox->setEnabled(enable);
    m_improveCacheLocalityCheckBox->setEnabled(enable);
    m_optimizeMeshesCheckBox->setEnabled(enable);
    m_generateNormalsCheckBox->setEnabled(enable);
    m_generateSmoothNormalsCheckBox->setEnabled(enable);
    m_calculateTangentSpaceCheckBox->setEnabled(enable);
    m_fixInfacingNormalsCheckBox->setEnabled(enable);
    m_removeRedundantMaterialsCheckBox->setEnabled(enable);
    m_embedTexturesCheckBox->setEnabled(enable);
    m_findDegeneratesCheckBox->setEnabled(enable);
    m_findInvalidDataCheckBox->setEnabled(enable);
    m_validateDataStructureCheckBox->setEnabled(enable);
    m_optimizeGraphCheckBox->setEnabled(enable);
    m_sortByPTypeCheckBox->setEnabled(enable);
    m_preTransformVerticesCheckBox->setEnabled(enable);
    m_splitLargeMeshesCheckBox->setEnabled(enable);
    m_limitBoneWeightsCheckBox->setEnabled(enable);
    m_flipUVsCheckBox->setEnabled(enable);
    m_flipWindingOrderCheckBox->setEnabled(enable);
    m_splitByBoneCountCheckBox->setEnabled(enable);
    m_deboneCheckBox->setEnabled(enable);
    m_forceGenNormalsCheckBox->setEnabled(enable);
    m_dropNormalsCheckBox->setEnabled(enable);
    m_genUVCoordsCheckBox->setEnabled(enable);
    m_transformUVCoordsCheckBox->setEnabled(enable);
    m_findInstancesCheckBox->setEnabled(enable);
    m_reverseWindingOrderCheckBox->setEnabled(enable);
    m_invertNormalsCheckBox->setEnabled(enable);
    
    // 缩放控制控件
    m_scaleSlider->setEnabled(enable);
    m_scaleSpinBox->setEnabled(enable);
    m_resetScaleButton->setEnabled(enable);
    m_resetViewButton->setEnabled(enable);
    

}

void MainWindow::onOpenModel()
{
    onSelectInputFile();
}

void MainWindow::onPreviewModel()
{
    QString filePath = QFileDialog::getOpenFileName(this, "选择模型文件", "",
                                                    "3D模型文件 (*.fbx *.obj *.dae *.3ds *.stl *.ply *.gltf *.glb "
                                                    "*.blend *.ase *.ifc *.xgl *.zgl *.ply *.dxf *.lwo *.lws *.lxo "
                                                    "*.stl *.x *.ac *.ms3d *.cob *.scn *.bvh *.csm *.xml *.irrmesh "
                                                    "*.irr *.mdl *.md2 *.md3 *.3d *.m3d *.ogex *.sib *.b3d *.q3d *.q3s "
                                                    "*.nff *.off *.pk3 *.md5mesh *.md5anim *.md5camera *.smd *.vta *.mdc "
                                                    "*.mdx *.sln *.x *.hmp *.ter *.uc *.3d *.mesh *.obj *.fbx);;所有文件 (*)");
    
    if (!filePath.isEmpty()) {
        m_inputFileEdit->setText(filePath);
        
        // 提供选择：直接预览还是内存加载预览
        QMessageBox msgBox;
        msgBox.setText("选择预览方式");
        msgBox.setInformativeText("您想使用哪种预览方式？\n\n直接预览：从文件直接加载\n内存加载预览：先将文件读入内存再加载");
        QPushButton *directButton = msgBox.addButton("直接预览", QMessageBox::ActionRole);
        QPushButton *memoryButton = msgBox.addButton("内存加载预览", QMessageBox::ActionRole);
        
        msgBox.setDefaultButton(directButton);
        
        msgBox.exec();
        
        if (msgBox.clickedButton() == directButton) {
            previewModel(filePath);
        } else if (msgBox.clickedButton() == memoryButton) {
            previewModelFromFileToMemory(filePath);
        }
    }
}

void MainWindow::previewModel(const QString &filePath)
{
    if (filePath.isEmpty()) {
        QMessageBox::warning(this, "警告", "文件路径为空！");
        return;
    }
    
    statusBar()->showMessage("正在加载模型...");

    QFileInfo fileInfo(filePath);
    QString extension = fileInfo.suffix().toLower();

    unsigned int importFlags = aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_OptimizeMeshes;

    ModelLoaderThread* loader = new ModelLoaderThread(filePath, importFlags, this);
    connect(loader, &ModelLoaderThread::modelLoaded, this, &MainWindow::onModelLoaded);
    connect(loader, &ModelLoaderThread::loadError, this, &MainWindow::onModelLoadError);
    connect(loader, &ModelLoaderThread::finished, loader, &ModelLoaderThread::deleteLater);
    loader->start();
}

void MainWindow::onModelLoaded(const aiScene* scene, Assimp::Importer* importer, const QString& filePath) {
    m_importers.append(importer);

    m_modelPreview->setModelScene(scene, filePath);

    m_modelPreview->show();
    m_modelPreview->update();

    qDebug() << "ModelPreview visible:" << m_modelPreview->isVisible();
    qDebug() << "ModelPreview size:" << m_modelPreview->size();

    m_modelPreview->resetScale();
    m_scaleSlider->setValue(100);
    m_scaleSpinBox->setValue(1.0);

    // 显示模型信息
    if (scene) {
        qDebug() << "📊 模型加载成功，详细信息:";
        qDebug() << "   📁 文件路径:" << filePath;
        qDebug() << "   🎯 网格数量:" << scene->mNumMeshes;
        qDebug() << "   🎭 材质数量:" << scene->mNumMaterials;
        qDebug() << "   🎬 动画数量:" << scene->mNumAnimations;
        qDebug() << "   🏗️ 纹理数量:" << scene->mNumTextures;
        qDebug() << "   💡 光源数量:" << scene->mNumLights;
        qDebug() << "   📷 相机数量:" << scene->mNumCameras;
    }

    statusBar()->showMessage("模型加载完成");
}

void MainWindow::onModelLoadError(const QString& error) {
    QMessageBox::critical(this, "错误", "无法加载模型文件进行预览：" + error);
    statusBar()->showMessage("模型加载失败: " + error);
}

void MainWindow::previewModelFromFileToMemory(const QString& filePath) {
    if (filePath.isEmpty()) {
        QMessageBox::warning(this, "警告", "文件路径为空！");
        return;
    }

    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        QMessageBox::critical(this, "错误", "无法打开文件：" + file.errorString());
        return;
    }

    // 读取文件到内存
    QByteArray fileData = file.readAll();
    file.close();

    if (fileData.isEmpty()) {
        QMessageBox::warning(this, "警告", "文件内容为空！");
        return;
    }

    // 使用内存加载方式
    previewModelFromMemory(fileData, QFileInfo(filePath).fileName());
}

void MainWindow::previewModelFromMemory(const QByteArray& fileData, const QString& fileName) {
    if (fileData.isEmpty()) {
        QMessageBox::warning(this, "警告", "文件数据为空！");
        return;
    }
    
    statusBar()->showMessage("正在从内存加载模型...");

    // 确定导入标志
    QFileInfo fileInfo(fileName);
    QString extension = fileInfo.suffix().toLower();

    unsigned int importFlags = aiProcess_Triangulate |
            aiProcess_GenNormals |
            aiProcess_OptimizeGraph;

    if (extension == "glb" || extension == "gltf") {
        importFlags |= aiProcess_FlipUVs;
        importFlags |= aiProcess_TransformUVCoords;
        importFlags |= aiProcess_GenUVCoords;
        importFlags |= aiProcess_EmbedTextures;
    } else {
        importFlags |= aiProcess_FlipUVs;
    }

    // 使用内存加载方式
    ModelLoaderThread* loader = new ModelLoaderThread(fileData, fileName, importFlags, this);
    connect(loader, &ModelLoaderThread::modelLoaded, this, &MainWindow::onModelLoaded);
    connect(loader, &ModelLoaderThread::loadError, this, &MainWindow::onModelLoadError);
    connect(loader, &ModelLoaderThread::finished, loader, &ModelLoaderThread::deleteLater);
    loader->start();
}

void MainWindow::onAbout()
{
    QMessageBox::about(this, "关于",
                       "3D模型轻量化工具 v1.0\n\n"
                       "基于Assimp库开发的3D模型优化工具\n"
                       "支持多种3D文件格式的导入和导出\n"
                       "提供全面的模型优化和压缩功能");
}

void MainWindow::onExit()
{
    QApplication::quit();
}





void MainWindow::onOutputPreviewClicked()
{
    QString outputPath = m_outputFileEdit->text();
    if (!outputPath.isEmpty()) {
        QFileInfo fileInfo(outputPath);
        if (fileInfo.exists()) {
            // 如果输出路径存在且是一个文件，则打开其所在的目录
            if (fileInfo.isFile()) {
                QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absolutePath()));
            }
            // 如果输出路径是一个目录，则直接打开该目录
            else if (fileInfo.isDir()) {
                QDesktopServices::openUrl(QUrl::fromLocalFile(outputPath));
            }
        } else {
            // 如果路径不存在，尝试打开其父目录
            QDir dir(outputPath);
            if (dir.exists()) {
                QDesktopServices::openUrl(QUrl::fromLocalFile(outputPath));
            } else {
                // 尝试获取父目录
                QDir parentDir = dir.filePath("..");
                if (parentDir.exists()) {
                    QDesktopServices::openUrl(QUrl::fromLocalFile(parentDir.absolutePath()));
                } else {
                    QMessageBox::warning(this, "预览失败", "无法定位到指定的输出路径");
                }
            }
        }
    } else {
        QMessageBox::information(this, "预览提示", "请先选择输出路径");
    }
}

void MainWindow::onInputPreviewClicked()
{
    QString inputPath = m_inputFileEdit->text();
    if (!inputPath.isEmpty()) {
        QFileInfo fileInfo(inputPath);
        if (fileInfo.exists()) {
            // 如果输入路径存在，则在模型预览窗口中显示模型
            if (fileInfo.isFile()) {
                // 提供选择：直接预览还是内存加载预览
                QMessageBox msgBox;
                msgBox.setText("选择预览方式");
                msgBox.setInformativeText("您想使用哪种预览方式？");
                QPushButton *directButton = msgBox.addButton("直接预览", QMessageBox::ActionRole);
                QPushButton *memoryButton = msgBox.addButton("内存加载预览", QMessageBox::ActionRole);
                QPushButton *cancelButton = msgBox.addButton(QMessageBox::Cancel);
                
                msgBox.exec();
                
                if (msgBox.clickedButton() == directButton) {
                    previewModel(inputPath);
                } else if (msgBox.clickedButton() == memoryButton) {
                    previewModelFromFileToMemory(inputPath);
                }
                // 如果点击取消，什么都不做
            }
            // 如果是目录，则在文件管理器中打开
            else if (fileInfo.isDir()) {
                QDesktopServices::openUrl(QUrl::fromLocalFile(inputPath));
            }
        } else {
            QMessageBox::warning(this, "预览失败", "指定的输入文件不存在");
        }
    } else {
        QMessageBox::information(this, "预览提示", "请先选择输入模型文件");
    }
}

// 新增：缩放控制槽函数实现
void MainWindow::onScaleSliderChanged(int value)
{
    // 将滑块值转换为缩放值 (1-200 -> 0.001-100.0)
    // 使用对数映射：中间位置(100)对应缩放值1
    float scale;
    if (value <= 100) {
        // 1-100 -> 0.001-1.0 (对数映射)
        scale = 0.001f * pow(1000.0f, (value - 1) / 99.0f);
    } else {
        // 101-200 -> 1.0-100.0 (对数映射)
        scale = pow(100.0f, (value - 100) / 100.0f);
    }
    
    m_scaleSpinBox->blockSignals(true);
    m_scaleSpinBox->setValue(scale);
    m_scaleSpinBox->blockSignals(false);
    m_modelPreview->setScale(scale);
    
    // 调试信息
    if (value == 100) {
        qDebug() << "Slider at center (100) -> Scale:" << scale;
    }
}

void MainWindow::onScaleSpinBoxChanged(double value)
{
    // 将缩放值转换为滑块值 (0.001-100.0 -> 1-200)
    int sliderValue;
    if (value <= 1.0) {
        // 0.001-1.0 -> 1-100 (对数映射)
        sliderValue = 1 + static_cast<int>(99.0 * log10(value / 0.001) / log10(1000.0));
    } else {
        // 1.0-100.0 -> 101-200 (对数映射)
        sliderValue = 100 + static_cast<int>(100.0 * log10(value) / log10(100.0));
    }
    
    // 确保值在有效范围内
    sliderValue = qBound(1, sliderValue, 200);
    
    m_scaleSlider->blockSignals(true);
    m_scaleSlider->setValue(sliderValue);
    m_scaleSlider->blockSignals(false);
    m_modelPreview->setScale(static_cast<float>(value));
}

void MainWindow::onResetScaleClicked()
{
    m_modelPreview->resetScale();
    m_scaleSlider->setValue(100); // 重置为1.0
    m_scaleSpinBox->setValue(1.0);
}

void MainWindow::onResetViewClicked()
{
    m_modelPreview->resetView();
    m_scaleSlider->setValue(100); // 重置为1.0
    m_scaleSpinBox->setValue(1.0);
}

void MainWindow::onModelPreviewScaleChanged(float scale)
{
    // 同步UI控件，避免循环信号
    m_scaleSlider->blockSignals(true);
    m_scaleSpinBox->blockSignals(true);
    
    // 将缩放值转换为滑块值 (0.001-100.0 -> 1-200)
    int sliderValue;
    if (scale <= 1.0f) {
        // 0.001-1.0 -> 1-100 (对数映射)
        sliderValue = 1 + static_cast<int>(99.0 * log10(scale / 0.001) / log10(1000.0));
    } else {
        // 1.0-100.0 -> 101-200 (对数映射)
        sliderValue = 100 + static_cast<int>(100.0 * log10(scale) / log10(100.0));
    }
    
    // 确保值在有效范围内
    sliderValue = qBound(1, sliderValue, 200);
    
    m_scaleSlider->setValue(sliderValue);
    m_scaleSpinBox->setValue(static_cast<double>(scale));
    
    m_scaleSlider->blockSignals(false);
    m_scaleSpinBox->blockSignals(false);
}

void MainWindow::onAnimationListChanged()
{
    // 更新动画列表
    ui->animationListWidget->clear();
    
    QVector<AnimationInfo> animationList = m_modelPreview->getAnimationList();
    for (int i = 0; i < animationList.size(); i++) {
        const AnimationInfo &anim = animationList[i];
        QString itemText = QString("%1 (%2 通道)").arg(anim.name).arg(anim.channelCount);
        QListWidgetItem *item = new QListWidgetItem(itemText);
        item->setData(Qt::UserRole, i); // 存储动画索引
        ui->animationListWidget->addItem(item);
    }
    
    // 更新按钮状态
    bool hasAnimations = !animationList.isEmpty();
    ui->playAnimationButton->setEnabled(hasAnimations);
    ui->stopAnimationButton->setEnabled(false);
    ui->pauseAnimationButton->setEnabled(false);
    ui->resumeAnimationButton->setEnabled(false);
    
    // 更新信息标签
    if (hasAnimations) {
        ui->animationInfoLabel->setText(QString("找到 %1 个动画，双击列表项或点击播放按钮开始播放").arg(animationList.size()));
    } else {
        ui->animationInfoLabel->setText("未找到动画");
    }
}

void MainWindow::onAnimationStateChanged(int animationIndex, bool isPlaying)
{
    // 更新列表项显示
    for (int i = 0; i < ui->animationListWidget->count(); i++) {
        QListWidgetItem *item = ui->animationListWidget->item(i);
        if (item->data(Qt::UserRole).toInt() == animationIndex) {
            QString itemText = item->text();
            if (isPlaying) {
                if (!itemText.contains("▶")) {
                    item->setText(itemText + " ▶");
                }
            } else {
                item->setText(itemText.replace(" ▶", ""));
            }
            break;
        }
    }
    
    // 更新按钮状态
    ui->playAnimationButton->setEnabled(!isPlaying);
    ui->stopAnimationButton->setEnabled(isPlaying);
    ui->pauseAnimationButton->setEnabled(isPlaying);
    ui->resumeAnimationButton->setEnabled(false);
    
    // 更新信息标签
    if (isPlaying) {
        QVector<AnimationInfo> animationList = m_modelPreview->getAnimationList();
        if (animationIndex >= 0 && animationIndex < animationList.size()) {
            const AnimationInfo &anim = animationList[animationIndex];
            ui->animationInfoLabel->setText(QString("正在播放: %1 (持续时间: %2 秒)").arg(anim.name).arg(anim.duration / anim.ticksPerSecond, 0, 'f', 2));
        }
    } else {
        ui->animationInfoLabel->setText("动画已停止");
    }
}

void MainWindow::onPlayAnimationClicked()
{
    // 获取当前选中的动画
    QListWidgetItem *currentItem = ui->animationListWidget->currentItem();
    if (currentItem) {
        int animationIndex = currentItem->data(Qt::UserRole).toInt();
        m_modelPreview->playAnimation(animationIndex);
    } else if (ui->animationListWidget->count() > 0) {
        // 如果没有选中项，播放第一个动画
        m_modelPreview->playAnimation(0);
        ui->animationListWidget->setCurrentRow(0);
    }
}

void MainWindow::onStopAnimationClicked()
{
    m_modelPreview->stopAnimation();
}

void MainWindow::onPauseAnimationClicked()
{
    m_modelPreview->pauseAnimation();
    
    // 更新按钮状态
    ui->pauseAnimationButton->setEnabled(false);
    ui->resumeAnimationButton->setEnabled(true);
    
    ui->animationInfoLabel->setText("动画已暂停");
}

void MainWindow::onResumeAnimationClicked()
{
    m_modelPreview->resumeAnimation();
    
    // 更新按钮状态
    ui->pauseAnimationButton->setEnabled(true);
    ui->resumeAnimationButton->setEnabled(false);
    
    // 更新信息标签
    int currentIndex = m_modelPreview->getCurrentAnimationIndex();
    if (currentIndex >= 0) {
        QVector<AnimationInfo> animationList = m_modelPreview->getAnimationList();
        if (currentIndex < animationList.size()) {
            const AnimationInfo &anim = animationList[currentIndex];
            ui->animationInfoLabel->setText(QString("正在播放: %1 (持续时间: %2 秒)").arg(anim.name).arg(anim.duration / anim.ticksPerSecond, 0, 'f', 2));
        }
    }
}

void MainWindow::onAnimationListItemDoubleClicked(QListWidgetItem *item)
{
    int animationIndex = item->data(Qt::UserRole).toInt();
    m_modelPreview->playAnimation(animationIndex);
}

// 视图控制槽函数实现
void MainWindow::onFrontViewClicked()
{
    m_modelPreview->setFrontView();
    statusBar()->showMessage("切换到前视图");
}

void MainWindow::onBackViewClicked()
{
    m_modelPreview->setBackView();
    statusBar()->showMessage("切换到后视图");
}

void MainWindow::onLeftViewClicked()
{
    m_modelPreview->setLeftView();
    statusBar()->showMessage("切换到左视图");
}

void MainWindow::onRightViewClicked()
{
    m_modelPreview->setRightView();
    statusBar()->showMessage("切换到右视图");
}

void MainWindow::onTopViewClicked()
{
    m_modelPreview->setTopView();
    statusBar()->showMessage("切换到顶视图");
}

void MainWindow::onBottomViewClicked()
{
    m_modelPreview->setBottomView();
    statusBar()->showMessage("切换到底视图");
}

void MainWindow::onRotationSensitivityChanged(int value)
{
    float sensitivity = value / 100.0f; // 将0-100转换为0.0-1.0
    m_modelPreview->setRotationSensitivity(sensitivity);
    statusBar()->showMessage(QString("旋转敏感度设置为: %1").arg(sensitivity, 0, 'f', 2));
}

void MainWindow::onAutoAdjustCameraChanged(bool enabled)
{
    m_modelPreview->setAutoAdjustCamera(enabled);
    statusBar()->showMessage(QString("动画时自动调整相机: %1").arg(enabled ? "开启" : "关闭"));
}

void MainWindow::onShowLogDialog()
{
    if (m_logDialog) {
        m_logDialog->show();
        m_logDialog->raise();
        m_logDialog->activateWindow();
    }
}
